# Time-stamp: <30 Jun 00 16:42:44 giron1>

=head1 NAME

LISTSGEN - Lists generator package

=head1 SYNOPSIS

 use LISTSGEN;

 my $list = new LISTSGEN;

=head1 DESCRIPTION

This package contains methods to create and manipulate lists

=head1 AUTHOR

 Franck Giron
 $Id: LISTSGEN.pm,v 1.1 2007/10/08 09:26:03 schweitz Exp $

=head1 LOG

 $Log: LISTSGEN.pm,v $
 Revision 1.1  2007/10/08 09:26:03  schweitz
 version 2.4, lib vergessen

 Revision 1.3  2001/01/23 14:50:04  giron1
 Place of debug infos changed

 Revision 1.2  2000/05/12 14:59:04  giron1
 added a die if the number of indexes asked is greater than the number of lines in the file

 Revision 1.1  2000/04/27 16:51:57  giron1
 First version checked


=cut

package LISTSGEN;

use FileHandle;

#----------------------------------------------------------------------

=head1 FUNCTIONS

Here is a description of the functions used

=head2 new - prompt list constructor

=cut

sub new {
  my $list = shift;
  my $class = ref($list) || $list;
  my $self = {};
  bless $self, $class;
  return $self;
}

#----------------------------------------------------------------------

=head2 readfile ($file)

reads a list of prompts in a file

=cut

sub readfile {
  my $list = shift;
  my $file = shift;

  my $debug = 1;
  my $count = 0;
  # open new FileHandle
  my $fh = new FileHandle;
  if ($fh->open("< $file")) {
    $debug && warn "reading list $file:\n";
    while (<$fh>) {
      chop;
      next if ($_ eq '');
      next if (m/^\s*\#/); #this is a comment
      s/^\s//; s/\s+/ /;   #substitute spaces
      $list->{$count} = $_; #store the line
      $count++;
    }
    $fh->close;
    $debug && warn "$count entries.\n";
  } else {warn "Cannot open list: $file\n";}
  return $count;
}

#----------------------------------------------------------------------

=head2 readvarlist ($file)

reads a list of variables associated with prompts file

=cut

sub readvarlist {
  my $list = shift;
  my $file = shift;

  my $debug = 1;
  # open new FileHandle
  my $fh = new FileHandle;
  if ($fh->open("< $file")) {
    $debug && warn "reading list: $file\n";
    while (<$fh>) {
      chop;
      next if ($_ eq '');
      next if (m/^\s*\#/); #this is a comment
      # reads each entry
      my ($varname,$file,$lines,$code) = split /\s/;
      $list->{$varname}{'file'} = $file;
      $list->{$varname}{'lines'} = $lines;
      $list->{$varname}{'code'} = $code;
    }
    $fh->close;
  } else {die "cannot open list: $file\n";}
}

#----------------------------------------------------------------------

=head2 genrandfrom ($list,$opt)

generate a new random list extracted from $list

=cut

sub genrandfrom {
  my $rand = shift;
  my $list = shift;
  my $opt = shift;

  my $debug = 1;
  # get the index of the maximum elements available in the list
  my $max = (keys %$list);

  $max--;

  $debug && warn "max=$max\n";

  # create the first entry in the hash
  my $l = int rand $max;
  $rand->{$l} = $list->{$l};

  # now creates a total of n element all with a different entry
  my $nlist = 1;
  while ($nlist < $opt->{nelem}{string}) {
    $l = int (rand($max) + 0.5);
    $debug && warn "l=$l\n";
    # element should not be defined already
    if (not defined $rand->{$l}) {
      $rand->{$l} = $list->{$l};
      $nlist++;
    }
  }
}

#----------------------------------------------------------------------

=head2 genrandindex ($list,$n)

generate a new index random list of $n elem

=cut

sub genrandindex {
  my $list = shift;
  my $n = shift;

  my $debug = 0;
  # get the index of the maximum elements available in the list
  my $max = (keys %$list);
  die "cannot generate more indexes ($n) than present in the original list ($max)\n" if ($n > $max);
  $debug and warn "max=$max\n";

  # create the first entry in list
  my @randind = ();
  my $l = int rand $max;
  push @randind, $l;
  # temporary hash to check double entries
  my %randh = ("$l" => "$l");

  # now creates a total of n elements all with a different entry
  my $nlist = 1;
  while ($nlist < $n) {
    $l = int rand($max);
    # element should not be defined already
    if (not defined $randh{$l}) {
      $debug && warn "l=$l\n";
      $randh{$l} = $l;
      push @randind, $l;
      $nlist++;
    }
  }
  return @randind;
}

#----------------------------------------------------------------------

=head2 substitutevarfrom (\%varprompts)

substitutes a variable by a prompt taken randomly from the hash
I<%varprompts>

=cut

sub substitutevarfrom {
  my $list = shift;
  my $varprompts = shift;

  my $debug = 0;
  my @varlist = keys %{$varprompts};
  my $pattern = '\b' . join('\b|\b',@varlist) . '\b';

  $debug && warn "pattern=$pattern\n";

  my ($var,$index,$seed,$key,$val);
  foreach $key (keys %$list) {
    $_ = $list->{$key};
    while (m/$pattern/) {
      $debug && warn "$_\n";
      $var = $&;
      $seed = $varprompts->{$var}{seed};
      # get a value
      $index = int (rand($seed));
      $debug && warn "$var,$seed,$index\n";
      $val = $varprompts->{$var}{prompts}->{$index};
      if (not defined($val)) {
	warn  "$_,$seed,$index.\n";
      }
      $debug && warn "$var,$index,$val\n";
      s/$var/$val/;
    }
    $list->{$key} = $_;
  }
}

#----------------------------------------------------------------------

=head2 writelist ($opt, $n, \@randindex))

write each element from the list referenced by the random number list
I<@randindex> in the prompts file with extension number I<$n>

=cut

sub writelist {
  my $list = shift;
  my $opt = shift;
  my $n = shift;
  my $indexref = shift;

  # Creates the file name numbered $n
  my $filen = "$opt->{pname}{string}.$n";

  # Open prompt file n
  my $fh = new FileHandle;
  $fh->open("> $filen") or die "cannot open $filen\n";
  $opt->{debug}{Do} && warn "opening $filen\n";

  # Writes each element in a numbered list form
  my $code = 0;
  if ($opt->{renum}{Do}) {$code = $opt->{pstart}{string};}

  foreach (@$indexref) {
    $code = $opt->{pstart}{string} + $_ unless ($opt->{renum}{Do});
    $fh->print("$code:$list->{$_}\n");
    if ($opt->{renum}{Do}) {$code++;}
  }
  $fh->close;
}

1;
